﻿#include "xpushbutton_p.h"

XPushButtonPrivate::XPushButtonPrivate()
    : objectXCoil(nullptr),
      pushButtonOperate(Set_ON),
      delayEnable(false),
      delayType(Constant),
      delayTimeRegister(nullptr),
      delayTimeConstant(0),
      dispalyText("ON")
{

}

XPushButtonPrivate::~XPushButtonPrivate()
{

}

XPushButton::XPushButton(QWidget *parent)
    : XPushButtonFunction(parent),
      xPushButtonP(new XPushButtonPrivate)
{

}

XPushButton::~XPushButton()
{
    delete xPushButtonP;
}

/*!
    \property XPushButton::objectXCoil
    \brief the coil as the button's object

    The default objectXCoil is nullptr.

    \sa indent
*/
XCoil *XPushButton::getObjectXCoil() const
{
    return xPushButtonP->objectXCoil;
}

void XPushButton::setObjectXCoil(XCoil *xCoil)
{
qDebug() << "setObjectXCoil";
    if(xPushButtonP->objectXCoil == xCoil)
        return;

    xPushButtonP->objectXCoil = xCoil;
}

/*!
    \property XPushButton::pushButtonOperate
    \brief the operate of xPushButton

    The default pushButtonOperate is Set_ON.

    \sa indent
*/
PushButtonOperate XPushButton::getPushButtonOperate() const
{
    return xPushButtonP->pushButtonOperate;
}

void XPushButton::setPushButtonOperate(PushButtonOperate operate)
{
qDebug() << "setPushButtonOperate";
//    if(xPushButtonP->pushButtonOperate == operate)
//        return;

    //删除当前按钮操作设置
    updateOperate(0);
    //设置按钮操作
    xPushButtonP->pushButtonOperate = operate;
    //更新按钮操作设置
    updateOperate(1);

    //根据设置的按钮操作设置按钮的操作和显示
    switch (xPushButtonP->pushButtonOperate)
    {
    case Set_ON:
    {
        xPushButtonP->dispalyText = "ON";
        break;
    }
    case Set_OFF:
    {
        xPushButtonP->dispalyText = "OFF";
        break;
    }
    case Set_REVERSE:
    {
        xPushButtonP->dispalyText = "REVERSE";
        break;
    }
    case Set_Instantaneous_On:
    {
        xPushButtonP->dispalyText = "Instantaneous On";
        break;
    }
    }
}

/*!
    \property XPushButton::delayEnable
    \brief whether or not use delay

    The default delayEnable is false.

    \sa indent
*/
bool XPushButton::getDelayEnable() const
{
    return xPushButtonP->delayEnable;
}

void XPushButton::setDelayEnable(bool enable)
{
    if(xPushButtonP->delayEnable == enable)
        return;
    xPushButtonP->delayEnable = enable;
}

/*!
    \property XPushButton::delayType
    \brief the delay's type

    The default delayType is Constant.

    \sa indent
*/
NumberType XPushButton::getDelayType() const
{
    return xPushButtonP->delayType;
}

void XPushButton::setDelayType(NumberType type)
{
    if(xPushButtonP->delayType == type)
        return;
    xPushButtonP->delayType = type;
}

/*!
    \property XPushButton::delayTimeRegister
    \brief the register as the delay time

    The default delayTimeRegister is nullptr.

    \sa indent
*/
XRegister *XPushButton::getDelayTimeRegister() const
{
    return xPushButtonP->delayTimeRegister;
}

void XPushButton::setDelayTimeRegister(XRegister *xRegister)
{
    if((!xPushButtonP->delayEnable) || (Variable != xPushButtonP->delayType))
        return;

    xPushButtonP->delayTimeRegister = xRegister;
}

/*!
    \property XPushButton::delayTimeConstant
    \brief the constant as the delay time

    The default delayTimeConstant is 0.

    \sa indent
*/
int XPushButton::getDelayTimeConstant() const
{
    return xPushButtonP->delayTimeConstant;
}

void XPushButton::setDelayTimeConstant(int value)
{
    if((!xPushButtonP->delayEnable) || (Constant != xPushButtonP->delayType))
        return;

    xPushButtonP->delayTimeConstant = value;
}

/*!
 * \brief XPushButton::paintEvent
 * \param ev
 */
void XPushButton::paintEvent(QPaintEvent *ev)
{
    //绘制准备工作,启用反锯齿
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    if(this->getDisplayEnable())
        this->setText(xPushButtonP->dispalyText);

    QPushButton::paintEvent(ev);
}

/*!
 * \brief XPushButton::mousePressEvent
 * \param ev
 */
void XPushButton::mousePressEvent(QMouseEvent *ev)
{
    //设置延时
    if(xPushButtonP->delayEnable)
    {
        switch (xPushButtonP->delayType)
        {
        case Constant:
        {
            Sleep(xPushButtonP->delayTimeConstant);
            break;
        }
        case Variable:
        {
            Sleep(xPushButtonP->delayTimeRegister->getRegisterValue());
            break;
        }
        }
    }

    XPushButtonFunction::mousePressEvent(ev);
}

/*!
 * \brief XPushButton::updateOperate
 * \param pattern
 *        0: delete
 *        1: add
 */
void XPushButton::updateOperate(int pattern)
{
qDebug() << "updateOperate" << pattern;
    //未设置线圈对象则退出
    if(!xPushButtonP->objectXCoil)
        return;

    //根据当前按钮操作属性更新
    switch (xPushButtonP->pushButtonOperate)
    {
    case Set_ON:
    {
        if(pattern)
        {
            XFunction xFunction(xPushButtonP->objectXCoil);
            func = &XFunction::setCoil;
            insertFunction(PressInstance, xFunction, func);
        }
        else
        {
            deleteFunction(PressInstance, 1);
        }

        break;
    }
    case Set_OFF:
    {
        if(pattern)
        {
            XFunction xFunction(xPushButtonP->objectXCoil);
            func = &XFunction::resetCoil;
            insertFunction(PressInstance, xFunction, func);
        }
        else
        {
            deleteFunction(PressInstance, 1);
        }

        break;
    }
    case Set_REVERSE:
    {
        if(pattern)
        {
            XFunction xFunction(xPushButtonP->objectXCoil);
            func = &XFunction::reverseCoil;
            insertFunction(PressInstance, xFunction, func);
        }
        else
        {
            deleteFunction(PressInstance, 1);
        }

        break;
    }
    case Set_Instantaneous_On:
    {
        if(pattern)
        {
            XFunction xFunction(xPushButtonP->objectXCoil);
            func = &XFunction::setCoil;
            insertFunction(PressInstance, xFunction, func);
            func = &XFunction::resetCoil;
            insertFunction(ReleaseInstance, xFunction, func);
        }
        else
        {
            deleteFunction(PressInstance, 1);
            deleteFunction(ReleaseInstance, 1);
        }

        break;
    }
    }
}
